home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-11-15 | 39.8 KB | 1,030 lines | [TEXT/R*ch] |
- {**************************************************** }
- { }
- { ResForkUtilities.p }
- { }
- { Written by: Keith R. Dunleavy }
- { (kdunleav@student.med.harvard.edu) }
- { }
- { Code history: }
- { Written for use with Symantec THINK Pascal 4.0 (Object Oriented) }
- { First created as Version 1.0 on 4/17/92 }
- { Icon plotting code added on 5/11/92 }
- { }
- { A conglomeration of Resource Fork utilities. }
- { }
- { ACKNOWLEDGEMENTS: }
- { * Code used for the plotting of icons was translated from Patrick C. Beard's }
- { C coded "ShowIconFamily" source (modified by: James W. Walker). }
- { * Code used for the obtainment of application version information was }
- { inspired by Apple's Developer Technical Support Notes #189 }
- { "Version Territory" }
- { }
- { COMMENTS: }
- { There are certainly ways to code these methods more efficiently. For }
- { instance, the seperate methods for PlotSmall and PlotLarge icons could be }
- { combined with some parameter passed in to make the necessary calcs }
- { which are different between the two resource formats. Nevertheless... }
- { these methods were written with the intent of helping out those who, }
- { like I was, are grapling with the tasks of mapping "things" to PixMaps. }
- { For a while I could find nobody who had concrete code for doing a color }
- { mapping to the screen. Eventually I got some good tips though. }
- { So... I included the fruits of these tips, and some other resource handlers }
- { for your enjoyment. I hope that they're helpfull. This is certainly }
- { EducationWare and is no big deal. If you do write a program that uses these }
- { methods 8.7 gazillion times... please just mention it. }
- { }
- { CORRECTIONS: }
- { Things can always be coded better. People usually make mistakes. So please, }
- { if you have any suggestions, corrections, questions, or even some helpful }
- { resource handler methods of your own... don't hesitate to drop me some }
- { EMail at the above address. }
- {**************************************************** }
-
- unit ResForkUtilities;
-
- interface
-
-
- {********************************************************************* }
- {* U T I L I T Y C O N S T A N T S * }
- {********************************************************************* }
- const
- MaxPossibleDepth = 8; { The maximum resource depth to check is 8 bits }
- SmallIconSide = 16; { The size of the "small icon" family is 16x16. }
- LargeIconSide = 32; { The size of the "Large icon" family is 32x32. }
-
- {********************************************************************* }
- {* U T I L I T Y T Y P E S * }
- {********************************************************************* }
- type
-
- { Resource Version Template }
- { Taken from Developer Technical Support Notes #189 "Version Territory" }
- NumVersion = packed record
- case integer of
- 0: (
- majorRev: SignedByte; { 1st part of version number in BCD }
- minorRev: 0..9; { 2nd part is 1 nibble in BCD }
- bugFixRev: 0..9; { 3rd part is 1 nibble in BCD }
- stage: signedByte; { stage code: dev, alpha, beta, final }
- nonRelRev: signedByte { revision level of non-released version }
- );
- 1: (
- version: LongInt { to use all 4 fields at one time }
- );
- end;
-
- VersRecPtr = ^VersRec;
- VersRecHandl = ^VersRecPtr;
- VersRec = record
- numericalVersion: NumVersion; { encoded version number }
- countryCode: integer; { country code from intl utilities }
- shortVersion: str255; { version number string - worst case }
- longVersion: str255; { LongMessage string packed after shortVersion }
- end;
-
- { Special BitMap pointer used for convincing CopyBits that it }
- { is receiving a BitMap when it is infact receiving a PixMap. }
- BitMapPtr = ^BitMap;
-
- {********************************************************************* }
- {* U T I L I T Y I N T E R F A C E S * }
- {********************************************************************* }
-
- function GetScreenDepth: Integer;
-
- procedure GetIndCLUT (var theColor: RGBColor; theCLUTRsrcID, theCLUTRsrcIndex: integer);
-
- function GetVersionString (var LVersionString, SVersionString: str255): Boolean;
-
- function GetSmallIcon (SmallIconID: Integer; var suggestedDepth: Integer): Handle;
- procedure PlotBWSmallIcon (BWSmallIcon: Handle; location: Point);
- procedure PlotCSmallIcon (CSmallIcon: Handle; SmallIconMaskID, Depth: integer; location: Point);
- procedure PlotSmallIcon (SmallIconID, DesiredDepth: integer; location: Point);
-
- function GetLargeIcon (LargeIconID: Integer; var suggestedDepth: Integer): Handle;
- procedure PlotBWLargeIcon (BWLargeIcon: Handle; location: Point);
- procedure PlotCLargeIcon (CLargeIcon: Handle; LargeIconMaskID, Depth: integer; location: Point);
- procedure PlotLargeIcon (LargeIconID, DesiredDepth: integer; location: Point);
-
- implementation
-
-
- {********************************************************************* }
- {* U T I L I T Y M E T H O D S * }
- {********************************************************************* }
-
-
- {----------------------------------------------------------- }
- { GetScreenDepth -- }
- { }
- { This function returns the current screen depth. }
- {----------------------------------------------------------- }
- function GetScreenDepth: Integer;
- var
- environment: SysEnvRec;
- theMainDevice: GDHandle;
- anError: OSErr;
- theDepth: Integer;
- begin
-
- { Determine the system environment. }
- anError := SysEnvirons(curSysEnvVers, environment);
-
- { Check to make sure that the system supports color QuickDraw. }
- if environment.hasColorQD then
- begin
- { Get a handle to the main device. }
- theMainDevice := GetMainDevice;
- { Determine the current depth being used. }
- theDepth := theMainDevice^^.gdPMap^^.pixelSize;
- { Check if the depth is set as being less than 4. If so, we want }
- { only possible icon depths (1,4,8) so set it to the next lowest. }
- if theDepth < 4 then
- theDepth := 1;
- end
- else
- { The environment indicated that the current system does not }
- { support color quickDraw, and thus we are dealing with a }
- { monochrome system. Ultimately, this means a depth of 1. }
- theDepth := 1;
-
- { Return the function value. }
- GetScreenDepth := theDepth;
-
- end;
- {------------------------------------------- }
- { End of function GetScreenDepth }
- {------------------------------------------- }
-
-
- {********************************************************************* }
- {* C O L O R L O O K - U P T A B L E (clut) H A N D L I N G M E T H O D S * }
- {********************************************************************* }
-
-
- {----------------------------------------------------------- }
- { GetIndCLUT -- }
- { }
- { Return the RGBColor found at a given index in a given }
- { clut resource. }
- {----------------------------------------------------------- }
- procedure GetIndCLUT (var theColor: RGBColor; theCLUTRsrcID, theCLUTRsrcIndex: integer);
- var
- aCTabHandle: CTabHandle;
- begin
-
- { Obtain the color look up table. }
- aCTabHandle := GetCTable(theCLUTRsrcID);
- { Check to make sure that the color look-up table could be found. }
- if aCTabHandle <> nil then
-
- { Now that we are sure that we have found a clut, make sure that }
- { the requested index is within the legal range for this clut. }
- { Keep in mind that all cluts are zero based arrays. }
- if ((theCLUTRsrcIndex >= 0) and (theCLUTRsrcIndex <= aCTabHandle^^.ctSize)) then
-
- begin
-
- { Lock down its handle. }
- HLock(Handle(aCTabHandle));
-
- { Set the value of the color retreived. }
- theColor := aCTabHandle^^.ctTable[theCLUTRsrcIndex].rgb;
-
- { Unlock the handle. }
- HUnlock(Handle(aCTabHandle));
-
- { Release the handle. }
- ReleaseResource(Handle(aCTabHandle));
-
- end;
- end;
- {------------------------------------------- }
- { End of procedure GetIndCLUT }
- {------------------------------------------- }
-
-
- {********************************************************************* }
- {* V E R S I O N (vers) H A N D L I N G M E T H O D S * }
- {********************************************************************* }
-
-
- {----------------------------------------------------------- }
- { GetVersionString -- }
- { }
- { This function returns the value of various version labels. }
- { Which are stored in the resource fork of the application. }
- { The version resource must be located at ID = 1. }
- { If the function could not (for whatever reason) obtain the }
- { version information, the function's value is returned as FALSE }
- {----------------------------------------------------------- }
- function GetVersionString (var LVersionString, SVersionString: str255): Boolean;
- const
- VersionRsrcID = 1; { the resource ID number }
- var
- Successful: Boolean; { flag for determining whether or not the obtaining of the vers info was succesful }
- aHandle: Handle;
- VersionPtr: VersRecPtr;
- begin
-
- { prime the returned flag... lets be optimistic. }
- Successful := TRUE;
-
- { our first job is to get version information from the resource template "vers" }
-
- aHandle := GetResource('vers', VersionRsrcID); { Load resource into memory }
-
- { check to see if the resource was indeed returned. }
- if aHandle <> nil then
- begin
-
- { Lock resource in heap }
- HLock(aHandle);
-
- { Get a type casted version the handle's pointer }
- VersionPtr := VersRecPtr(aHandle^);
-
- { extract the actual two strings of info which we want. }
- SVersionString := VersionPtr^.shortVersion;
- LVersionString := VersionPtr^.longVersion;
-
- { Unlock resource }
- HUnlock(aHandle);
-
- { alow the resource to be purged. }
- ReleaseResource(aHandle);
-
- end
- else
- { if we were unable to obtain a handle to the resource information }
- { return a value of FALSE. }
- Successful := FALSE;
-
- { return the function value. }
- GetVersionString := Successful;
-
- end;
- {------------------------------------------- }
- { End of function GetVersionString }
- {------------------------------------------- }
-
-
- {********************************************************************* }
- {* S M A L L I C O N (icsx) H A N D L I N G M E T H O D S * }
- {********************************************************************* }
-
-
-
- {----------------------------------------------------------- }
- { GetSmallIcon -- }
- { }
- { This function returns a handle the "deepest" possible small }
- { icon it can find. This will be either a ics8, ics4, or ics#. }
- { The function starts searching for the icon which coresponds }
- { to the "suggestedDepth" and, if not found, will search for }
- { a SmallIcon of the same ID, but lower depth. }
- { EXAMPLE: The function is called, looking for a small icon of }
- { ID=200. The suggestedDepth is 8. The function looks for a }
- { ics8 resource of ID=200. If found, its handle is returned. If }
- { it can't be located, the next logical depth to search is 4. }
- { Thus the function then looks for a ics4 of ID=200. If found, }
- { a handle to the ics4 is returned. If not found, on last attempt }
- { will be made to locate a usable SmallIcon. This time, the }
- { search will be for a depth of 1. Thus the function looks for }
- { a ics# of ID=200. Again, if found, the handle to the icon is }
- { returned. If no SmallIcon is found, then a nil is returned. }
- {----------------------------------------------------------- }
- function GetSmallIcon (SmallIconID: Integer; var suggestedDepth: Integer): Handle;
- var
- SmallIconH: Handle;
- ActualDepth: Integer;
- begin
-
- { Prime the local variables. }
- SmallIconH := nil;
- ActualDepth := suggestedDepth;
-
- { If the suggested depth is 8 bits (or mistakenly more) then }
- { search for an ics8 resource. }
- if suggestedDepth >= 8 then
- begin
- SmallIconH := GetResource('ics8', SmallIconID);
- { If the resource was indeed present, then }
- if SmallIconH <> nil then
- begin
- { Make sure that the suggestedDepth is set to reflect the }
- { small icons which was actually located. }
- suggestedDepth := 8;
- end
- else
- { No ics8 resource could be found at the given ID. Thus, set }
- { set the suggestedDepth to the next lowest depth. }
- suggestedDepth := 4;
- end;
-
- { If the suggested depth is 4 bits (or mistakenly 5-7), and no smallIcon }
- { has yet been located, then search for an ics4 resource. }
- if ((suggestedDepth < 8) and (suggestedDepth >= 4) and (SmallIconH = nil)) then
- begin
- SmallIconH := GetResource('ics4', SmallIconID);
- { If the resource was indeed present, then }
- if SmallIconH <> nil then
- begin
- { Make sure that the suggestedDepth is set to reflect the }
- { small icons which was actually located. }
- suggestedDepth := 4;
- end
- else
- { No ics4 resource could be found at the given ID. Thus, set }
- { set the suggestedDepth to the next lowest depth. }
- suggestedDepth := 1;
- end;
-
- { If the suggested depth is 1 bit (or mistakenly 2-3), and no smallIcon }
- { has yet been located, then search for an ics# resource. }
- if ((suggestedDepth < 4) and (SmallIconH = nil)) then
- begin
- SmallIconH := GetResource('ics#', SmallIconID);
- { If the resource was indeed present, then }
- if SmallIconH <> nil then
- begin
- { Make sure that the suggestedDepth is set to reflect the }
- { small icons which was actually located. }
- suggestedDepth := 1;
- end
- else
- { No ics# resource could be found at the given ID. Thus, set }
- { set the suggestedDepth to the next lowest depth. }
- suggestedDepth := 0;
- end;
-
- { Return the handle to the SmallIcon. }
- { If it is nil, then no smallIcon was found. Also if this is }
- { true, the suggestedDepth var parameter will be set to zero. }
- GetSmallIcon := SmallIconH;
-
- end;
- {------------------------------------------- }
- { End of function GetSmallIcon }
- {------------------------------------------- }
-
-
- {----------------------------------------------------------- }
- { PlotBWSmallIcon -- }
- { }
- { This procedure draws the ics# member of a SmallIcon }
- { family. This drawing is done in the current grafPort, with }
- { the upper left corner of the SmallIcon being located at the }
- { desired point. }
- { }
- { * For Reference: }
- { An ics# is a resource type which defines a 16 by 16 pixel }
- { black&white image of 1 bit depth, and thus a total of 32 }
- { bytes. It is also followed by the ics# mask or 32 bytes. }
- {----------------------------------------------------------- }
- procedure PlotBWSmallIcon (BWSmallIcon: Handle; location: Point);
- var
- Bounds: Rect;
- DestRect: Rect;
- BWSmallIconBitMap: BitMap;
-
- begin
-
- { Determine the bounds and destination rect of the smallIcon according to the passed in location parameter . }
- SetRect(bounds, 0, 0, SmallIconSide, SmallIconSide);
- SetRect(destRect, location.h, location.v, location.h + SmallIconSide, location.v + SmallIconSide);
-
- { Lock down our SmallIcon. }
- HLock(BWSmallIcon);
-
- { Prepare the SmallIcon Mask and destination bitmaps. }
- BWSmallIconBitMap.baseAddr := Ptr(LongInt(BWSmallIcon^) + 32);
- BWSmallIconBitMap.rowBytes := 2;
- BWSmallIconBitMap.bounds := Bounds;
-
- { Transfer the mask of the B&W SmallIcon. }
- CopyBits(BWSmallIconBitMap, thePort^.PortBits, bounds, DestRect, srcBic, nil);
-
- { Change the BitMap address pointer to get the ics# image as apposed to the current mask. }
- BWSmallIconBitMap.baseAddr := Ptr(BWSmallIcon^);
- { Transfer the SmallIcon image. }
- CopyBits(BWSmallIconBitMap, thePort^.PortBits, bounds, DestRect, srcOr, nil);
-
- { UnLock our SmallIcon. }
- HUnLock(BWSmallIcon);
-
- end;
- {------------------------------------------- }
- { End of procedure PlotBWSmallIcon }
- {------------------------------------------- }
-
-
-
- {----------------------------------------------------------- }
- { PlotCSmallIcon -- }
- { }
- { * This procedure draws the "deepest" color small icon it can. }
- { This is based on the determined depth of screen as well as }
- { available resources. }
- { * Once the small icon is identified and loaded, it is transfered }
- { to a PixelMap of either 4 or 8 bit depth, depending on }
- { whether it is an ics4 or ics8. }
- { * The small icon is drawn with its upper left corner situated }
- { at the desired location within the current grafCPort. }
- { }
- { * For Reference: }
- { * An ics8 is a resource type which defines a 16 by 16 pixel }
- { color image of 8 bit depth, and thus a total of 256 bytes. }
- { * An ics4 is a resource type which defines a 16 by 16 pixel }
- { color image of 4 bit depth, and thus a total of 128 bytes. }
- { * An ics# is a resource type which defines a 16 by 16 pixel }
- { black&white image of 1 bit depth, and thus a total of 32 }
- { bytes. It is also followed by the ics# mask or 32 bytes. }
- {----------------------------------------------------------- }
- procedure PlotCSmallIcon (CSmallIcon: Handle; SmallIconMaskID, Depth: integer; location: Point);
- var
- ScreenDepth: Integer; { Holds the determined depth of the screen. }
- SmallIconDepth: Integer; { Holds the highest found Small Icon depth (either 1,4, or 8) }
- { If no Small Icon can be found, then this holds the value zero. }
- ColorLookUpTable: CTabHandle; { Holds our own color look-up table. }
- destRect: Rect; { The rect which holds the end location of the small icon. }
- MaskIconHandle: Handle; { The handle which holds the small icon mask data. }
- SmallIconPixMap: PixMapHandle; { The color PixMap which holds the color image of the small icon. }
- SmallIconBitMap: BitMap; { The B&W bitMap which holds the B&W image of the small icon. }
- MaskBitMap: BitMap; { The B&W bitMap which holds the mask of the small icon. }
- bounds: Rect; { The rect which defines the bounds of the small icon. }
- rowBytes: integer; { Used to hold the calculation of the number of bytes in a row of the small icon. }
- aBitMapPtr: BitMapPtr; { A smecial type used to coerce the PixMap into looking like a BitMap. }
-
-
- {------------------------------ }
- { Set up failure handler. }
- {------------------------------ }
- procedure HandleFailure (error: Integer);
- begin
-
- { Take care of disposal or release of all handles allocated by us. }
-
- if ColorLookUpTable <> nil then
- DisposeCTable(ColorLookUpTable);
-
- if CSmallIcon <> nil then
- HUnLock(CSmallIcon);
-
- if MaskIconHandle <> nil then
- ReleaseResource(MaskIconHandle);
-
- if SmallIconPixMap <> nil then
- begin
- SmallIconPixMap^^.baseAddr := nil;
- DisposPixMap(SmallIconPixMap);
- end;
-
- Exit(PlotCSmallIcon);
- end;
- {------------------------------ }
- { End of failure handler. }
- {------------------------------ }
-
- begin
-
- { Initialize all of our handles so that error handling is assured of working. }
- ColorLookUpTable := nil;
- MaskIconHandle := nil;
- SmallIconPixMap := nil;
-
- { Check to make sure that a SmallIcon was indeed able to be found. }
- if CSmallIcon = nil then
- HandleFailure(resNotFound);
- { Lock down our icon. }
- HLock(CSmallIcon);
-
- { Determine the bounds and destination rect of the smallIcon according to the passed in location parameter . }
- SetRect(bounds, 0, 0, SmallIconSide, SmallIconSide);
- SetRect(destRect, location.h, location.v, location.h + SmallIconSide, location.v + SmallIconSide);
-
- { Get the mask data. }
- MaskIconHandle := GetResource('ics#', SmallIconMaskID);
- { Check to make sure that a SmallIcon mask was indeed able to be found. }
- if MaskIconHandle = nil then
- HandleFailure(resNotFound);
- { Lock down our mask. }
- HLock(MaskIconHandle);
-
- { Handle the plotting of a color smallIcon. }
-
- { Get the correct lookup table according to the depth of the SmallIcon. }
- ColorLookUpTable := GetCTable(Depth);
- { Check to see if the color lookUp table could be created. }
- if ColorLookUpTable = nil then
- HandleFailure(memFullErr);
-
- { Create a pixmap to stick the icon bits into for screen blitting. }
- SmallIconPixMap := NewPixMap;
- { Check to see if there was enough memory to create the new PixMap. }
- if SmallIconPixMap = nil then
- HandleFailure(memFullErr);
-
- { Set up the color pixmap with the correct bounds, depth, and clut. }
- rowBytes := (((Depth * SmallIconSide) + 15) div 16) * 2;
- SmallIconPixMap^^.baseAddr := Ptr(CSmallIcon^);
- SmallIconPixMap^^.rowBytes := BOR(rowBytes, $8000);
- SmallIconPixMap^^.bounds := bounds;
- SmallIconPixMap^^.pixelType := 0; { Chunky model. }
- SmallIconPixMap^^.pixelSize := Depth;
- SmallIconPixMap^^.cmpCount := 1; { If in 32 bit mode this will be 3, so must change. }
- SmallIconPixMap^^.cmpSize := Depth; { Only chunky images used. }
- DisposeCTable(SmallIconPixMap^^.pmTable); { Dispose of default, uninitialized table. }
- SmallIconPixMap^^.pmTable := ColorLookUpTable;
-
- { Prepare the SmallIcon mask. }
- MaskBitMap.baseAddr := Ptr(LongInt(MaskIconHandle^) + 32);
- MaskBitMap.rowBytes := 2;
- MaskBitMap.bounds := bounds;
-
- { Punch out the mask. }
- CopyBits(MaskBitMap, thePort^.portBits, bounds, destRect, srcBic, nil);
-
- { Draw the actual icon. }
- HLock(Handle(SmallIconPixMap));
- { In order to do this, we must disguise our PixMap as a BitMap. }
- aBitMapPtr := BitMapPtr(SmallIconPixMap^);
- CopyBits(aBitMapPtr^, thePort^.portBits, bounds, destRect, srcOr, nil);
-
- { Release all that we have allocated. }
- SmallIconPixMap^^.baseAddr := nil;
- DisposPixMap(SmallIconPixMap);
-
- { Release the mask resource handle. }
- ReleaseResource(MaskIconHandle);
-
- { Unlock our icon handle. }
- HUnLock(CSmallIcon);
-
- end;
- {------------------------------------------- }
- { End of procedure PlotCSmallIcon }
- {------------------------------------------- }
-
-
- {----------------------------------------------------------- }
- { PlotSmallIcon -- }
- { }
- { * This procedure draws the "deepest" small icon it can. }
- { This is based on the determined depth of screen as well as }
- { available resources. }
- { * Once identified, the SmallIcon is drawn by either the }
- { PlotBWSmallIcon or PlotCSmallIcon procedures. }
- { }
- {----------------------------------------------------------- }
- procedure PlotSmallIcon (SmallIconID, DesiredDepth: integer; Location: Point);
- var
- ScreenDepth: Integer; { Holds the determined depth of the screen. }
- SmallIconDepth: Integer; { Holds the highest found Small Icon depth (either 1,4, or 8) }
- { If no Small Icon can be found, then this holds the value zero. }
- SmallIconHandle: Handle; { The handle which holds the small icon data. }
-
- {------------------------------ }
- { Set up failure handler. }
- {------------------------------ }
- procedure HandleFailure (error: Integer);
- begin
-
- { Take care of disposal or release of all handles allocated by us. }
-
- if SmallIconHandle <> nil then
- ReleaseResource(SmallIconHandle);
-
- Exit(PlotSmallIcon);
- end;
- {------------------------------ }
- { End of failure handler. }
- {------------------------------ }
-
- begin
-
- { Initialize all of our handles so that error handling is assured of working. }
- SmallIconHandle := nil;
-
- { Determine the depth of the screen. }
- ScreenDepth := GetScreenDepth;
-
- { Now attempt to find the highest depth smallIcon available. }
- SmallIconDepth := ScreenDepth;
- SmallIconHandle := GetSmallIcon(SmallIconID, SmallIconDepth);
- { Check to make sure that a SmallIcon was indeed able to be found. }
- if SmallIconHandle = nil then
- HandleFailure(resNotFound);
-
- { Now we must differentiate between the plotting of a Black&White }
- { smallIcon and a color smallIcon. }
- if SmallIconDepth > 1 then
-
- { Handle the plotting of a color smallIcon. }
- { We must send the handle to the SmallIcon, the resID of the SmallIcon's }
- { mask (which is the ics# ID), the depth of the SmallIcon (which is }
- { either 4 or 8), and the desired location of the upper left corner. }
- begin
- PlotCSmallIcon(SmallIconHandle, SmallIconID, SmallIconDepth, Location);
- end
-
- else
-
- { Handle the plotting of a black&White smallIcon. }
- { We must send the handle to the SmallIcon, and the desired location of }
- { the upper left corner. }
- begin
- PlotBWSmallIcon(SmallIconHandle, Location);
- end;
-
- { Release the icon resource handle. }
- ReleaseResource(SmallIconHandle);
-
- end;
- {------------------------------------------- }
- { End of procedure PlotSmallIcon }
- {------------------------------------------- }
-
-
- {********************************************************************* }
- {* L A R G E I C O N (iclx) H A N D L I N G M E T H O D S * }
- {********************************************************************* }
-
-
- {----------------------------------------------------------- }
- { GetLargeIcon -- }
- { }
- { This function returns a handle the "deepest" possible Large }
- { icon it can find. This will be either a icl8, icl4, or ICN#. }
- { The function starts searching for the icon which coresponds }
- { to the "suggestedDepth" and, if not found, will search for }
- { a LargeIcon of the same ID, but lower depth. }
- { EXAMPLE: The function is called, looking for a Large icon of }
- { ID=200. The suggestedDepth is 8. The function looks for a }
- { icl8 resource of ID=200. If found, its handle is returned. If }
- { it can't be located, the next logical depth to search is 4. }
- { Thus the function then looks for a icl4 of ID=200. If found, }
- { a handle to the icl4 is returned. If not found, on last attempt }
- { will be made to locate a usable LargeIcon. This time, the }
- { search will be for a depth of 1. Thus the function looks for }
- { a ICN# of ID=200. Again, if found, the handle to the icon is }
- { returned. If no LargeIcon is found, then a nil is returned. }
- {----------------------------------------------------------- }
- function GetLargeIcon (LargeIconID: Integer; var suggestedDepth: Integer): Handle;
- var
- LargeIconH: Handle;
- ActualDepth: Integer;
- begin
-
- { Prime the local variables. }
- LargeIconH := nil;
- ActualDepth := suggestedDepth;
-
- { If the suggested depth is 8 bits (or mistakenly more) then }
- { search for an icl8 resource. }
- if suggestedDepth >= 8 then
- begin
- LargeIconH := GetResource('icl8', LargeIconID);
- { If the resource was indeed present, then }
- if LargeIconH <> nil then
- begin
- { Make sure that the suggestedDepth is set to reflect the }
- { Large icons which was actually located. }
- suggestedDepth := 8;
- end
- else
- { No icl8 resource could be found at the given ID. Thus, set }
- { set the suggestedDepth to the next lowest depth. }
- suggestedDepth := 4;
- end;
-
- { If the suggested depth is 4 bits (or mistakenly 5-7), and no LargeIcon }
- { has yet been located, then search for an icl4 resource. }
- if ((suggestedDepth < 8) and (suggestedDepth >= 4) and (LargeIconH = nil)) then
- begin
- LargeIconH := GetResource('icl4', LargeIconID);
- { If the resource was indeed present, then }
- if LargeIconH <> nil then
- begin
- { Make sure that the suggestedDepth is set to reflect the }
- { Large icons which was actually located. }
- suggestedDepth := 4;
- end
- else
- { No icl4 resource could be found at the given ID. Thus, set }
- { set the suggestedDepth to the next lowest depth. }
- suggestedDepth := 1;
- end;
-
- { If the suggested depth is 1 bit (or mistakenly 2-3), and no LargeIcon }
- { has yet been located, then search for an ICN# resource. }
- if ((suggestedDepth < 4) and (LargeIconH = nil)) then
- begin
- LargeIconH := GetResource('ICN#', LargeIconID);
- { If the resource was indeed present, then }
- if LargeIconH <> nil then
- begin
- { Make sure that the suggestedDepth is set to reflect the }
- { Large icons which was actually located. }
- suggestedDepth := 1;
- end
- else
- { No ICN# resource could be found at the given ID. Thus, set }
- { set the suggestedDepth to the next lowest depth. }
- suggestedDepth := 0;
- end;
-
- { Return the handle to the LargeIcon. }
- { If it is nil, then no LargeIcon was found. Also if this is }
- { true, the suggestedDepth var parameter will be set to zero. }
- GetLargeIcon := LargeIconH;
-
- end;
- {------------------------------------------- }
- { End of function GetLargeIcon }
- {------------------------------------------- }
-
-
-
- {----------------------------------------------------------- }
- { PlotBWLargeIcon -- }
- { }
- { This procedure draws the ICN# member of a LargeIcon }
- { family. This drawing is done in the current grafPort, with }
- { the upper left corner of the LargeIcon being located at the }
- { desired point. }
- { }
- { * For Reference: }
- { An ICN# is a resource type which defines a 32 by 32 pixel }
- { black&white image of 1 bit depth, and thus a total of 128 }
- { bytes. It is also followed by the ICN# mask or 128 bytes. }
- {----------------------------------------------------------- }
- procedure PlotBWLargeIcon (BWLargeIcon: Handle; location: Point);
- var
- Bounds: Rect;
- DestRect: Rect;
- BWLargeIconBitMap: BitMap;
-
- begin
-
- { Determine the bounds and destination rect of the LargeIcon according to the passed in location parameter . }
- SetRect(bounds, 0, 0, LargeIconSide, LargeIconSide);
- SetRect(destRect, location.h, location.v, location.h + LargeIconSide, location.v + LargeIconSide);
-
- { Lock down our LargeIcon. }
- HLock(BWLargeIcon);
-
- { Prepare the LargeIcon Mask and destination bitmaps. }
- BWLargeIconBitMap.baseAddr := Ptr(LongInt(BWLargeIcon^) + 128);
- BWLargeIconBitMap.rowBytes := 4;
- BWLargeIconBitMap.bounds := Bounds;
-
- { Transfer the mask of the B&W LargeIcon. }
- CopyBits(BWLargeIconBitMap, thePort^.PortBits, bounds, DestRect, srcBic, nil);
-
- { Change the BitMap address pointer to get the ICN# image as apposed to the current mask. }
- BWLargeIconBitMap.baseAddr := Ptr(BWLargeIcon^);
- { Transfer the LargeIcon image. }
- CopyBits(BWLargeIconBitMap, thePort^.PortBits, bounds, DestRect, srcOr, nil);
-
- { UnLock our LargeIcon. }
- HUnLock(BWLargeIcon);
-
- end;
- {------------------------------------------- }
- { End of procedure PlotBWLargeIcon }
- {------------------------------------------- }
-
-
-
- {----------------------------------------------------------- }
- { PlotCLargeIcon -- }
- { }
- { * This procedure draws the "deepest" color Large icon it can. }
- { This is based on the determined depth of screen as well as }
- { available resources. }
- { * Once the Large icon is identified and loaded, it is transfered }
- { to a PixelMap of either 4 or 8 bit depth, depending on }
- { whether it is an icl4 or icl8. }
- { * The Large icon is drawn with its upper left corner situated }
- { at the desired location within the current grafCPort. }
- { }
- { * For Reference: }
- { * An icl8 is a resource type which defines a 32 by 32 pixel }
- { color image of 8 bit depth, and thus a total of 1024 bytes. }
- { * An icl4 is a resource type which defines a 32 by 32 pixel }
- { color image of 4 bit depth, and thus a total of 512 bytes. }
- { * An ICN# is a resource type which defines a 16 by 16 pixel }
- { black&white image of 1 bit depth, and thus a total of 128 }
- { bytes. It is also followed by the ICN# mask or 128 bytes. }
- {----------------------------------------------------------- }
- procedure PlotCLargeIcon (CLargeIcon: Handle; LargeIconMaskID, Depth: integer; location: Point);
- var
- ScreenDepth: Integer; { Holds the determined depth of the screen. }
- LargeIconDepth: Integer; { Holds the highest found Large Icon depth (either 1,4, or 8) }
- { If no Large Icon can be found, then this holds the value zero. }
- ColorLookUpTable: CTabHandle; { Holds our own color look-up table. }
- destRect: Rect; { The rect which holds the end location of the Large icon. }
- MaskIconHandle: Handle; { The handle which holds the Large icon mask data. }
- LargeIconPixMap: PixMapHandle; { The color PixMap which holds the color image of the Large icon. }
- LargeIconBitMap: BitMap; { The B&W bitMap which holds the B&W image of the Large icon. }
- MaskBitMap: BitMap; { The B&W bitMap which holds the mask of the Large icon. }
- bounds: Rect; { The rect which defines the bounds of the Large icon. }
- rowBytes: integer; { Used to hold the calculation of the number of bytes in a row of the Large icon. }
- aBitMapPtr: BitMapPtr; { A smecial type used to coerce the PixMap into looking like a BitMap. }
-
-
- {------------------------------ }
- { Set up failure handler. }
- {------------------------------ }
- procedure HandleFailure (error: Integer);
- begin
-
- { Take care of disposal or release of all handles allocated by us. }
-
- if ColorLookUpTable <> nil then
- DisposeCTable(ColorLookUpTable);
-
- if CLargeIcon <> nil then
- HUnLock(CLargeIcon);
-
- if MaskIconHandle <> nil then
- ReleaseResource(MaskIconHandle);
-
- if LargeIconPixMap <> nil then
- begin
- LargeIconPixMap^^.baseAddr := nil;
- DisposPixMap(LargeIconPixMap);
- end;
-
- Exit(PlotCLargeIcon);
- end;
- {------------------------------ }
- { End of failure handler. }
- {------------------------------ }
-
- begin
-
- { Initialize all of our handles so that error handling is assured of working. }
- ColorLookUpTable := nil;
- MaskIconHandle := nil;
- LargeIconPixMap := nil;
-
- { Check to make sure that a LargeIcon was indeed able to be found. }
- if CLargeIcon = nil then
- HandleFailure(resNotFound);
- { Lock down our icon. }
- HLock(CLargeIcon);
-
- { Determine the bounds and destination rect of the LargeIcon according to the passed in location parameter . }
- SetRect(bounds, 0, 0, LargeIconSide, LargeIconSide);
- SetRect(destRect, location.h, location.v, location.h + LargeIconSide, location.v + LargeIconSide);
-
- { Get the mask data. }
- MaskIconHandle := GetResource('ICN#', LargeIconMaskID);
- { Check to make sure that a LargeIcon mask was indeed able to be found. }
- if MaskIconHandle = nil then
- HandleFailure(resNotFound);
- { Lock down our mask. }
- HLock(MaskIconHandle);
-
- { Handle the plotting of a color LargeIcon. }
-
- { Get the correct lookup table according to the depth of the LargeIcon. }
- ColorLookUpTable := GetCTable(Depth);
- { Check to see if the color lookUp table could be created. }
- if ColorLookUpTable = nil then
- HandleFailure(memFullErr);
-
- { Create a pixmap to stick the icon bits into for screen blitting. }
- LargeIconPixMap := NewPixMap;
- { Check to see if there was enough memory to create the new PixMap. }
- if LargeIconPixMap = nil then
- HandleFailure(memFullErr);
-
- { Set up the color pixmap with the correct bounds, depth, and clut. }
- rowBytes := (((Depth * LargeIconSide) + 15) div 16) * 2;
- LargeIconPixMap^^.baseAddr := Ptr(CLargeIcon^);
- LargeIconPixMap^^.rowBytes := BOR(rowBytes, $8000);
- LargeIconPixMap^^.bounds := bounds;
- LargeIconPixMap^^.pixelType := 0; { Chunky model. }
- LargeIconPixMap^^.pixelSize := Depth;
- LargeIconPixMap^^.cmpCount := 1; { If in 32 bit mode this will be 3, so must change. }
- LargeIconPixMap^^.cmpSize := Depth; { Only chunky images used. }
- DisposeCTable(LargeIconPixMap^^.pmTable); { Dispose of default, uninitialized table. }
- LargeIconPixMap^^.pmTable := ColorLookUpTable;
-
- { Prepare the LargeIcon mask. }
- MaskBitMap.baseAddr := Ptr(LongInt(MaskIconHandle^) + 128);
- MaskBitMap.rowBytes := 4;
- MaskBitMap.bounds := bounds;
-
- { Punch out the mask. }
- CopyBits(MaskBitMap, thePort^.portBits, bounds, destRect, srcBic, nil);
-
- { Draw the actual icon. }
- HLock(Handle(LargeIconPixMap));
- { In order to do this, we must disguise our PixMap as a BitMap. }
- aBitMapPtr := BitMapPtr(LargeIconPixMap^);
- CopyBits(aBitMapPtr^, thePort^.portBits, bounds, destRect, srcOr, nil);
-
- { Release all that we have allocated. }
- LargeIconPixMap^^.baseAddr := nil;
- DisposPixMap(LargeIconPixMap);
-
- { Release the mask resource handle. }
- ReleaseResource(MaskIconHandle);
-
- { Unlock our icon handle. }
- HUnLock(CLargeIcon);
-
- end;
- {------------------------------------------- }
- { End of procedure PlotCLargeIcon }
- {------------------------------------------- }
-
-
- {----------------------------------------------------------- }
- { PlotLargeIcon -- }
- { }
- { * This procedure draws the "deepest" Large icon it can. }
- { This is based on the determined depth of screen as well as }
- { available resources. }
- { * Once identified, the LargeIcon is drawn by either the }
- { PlotBWLargeIcon or PlotCLargeIcon procedures. }
- { }
- {----------------------------------------------------------- }
- procedure PlotLargeIcon (LargeIconID, DesiredDepth: integer; Location: Point);
- var
- ScreenDepth: Integer; { Holds the determined depth of the screen. }
- LargeIconDepth: Integer; { Holds the highest found Large Icon depth (either 1,4, or 8) }
- { If no Large Icon can be found, then this holds the value zero. }
- LargeIconHandle: Handle; { The handle which holds the Large icon data. }
-
- {------------------------------ }
- { Set up failure handler. }
- {------------------------------ }
- procedure HandleFailure (error: Integer);
- begin
-
- { Take care of disposal or release of all handles allocated by us. }
-
- if LargeIconHandle <> nil then
- ReleaseResource(LargeIconHandle);
-
- Exit(PlotLargeIcon);
- end;
- {------------------------------ }
- { End of failure handler. }
- {------------------------------ }
-
- begin
-
- { Initialize all of our handles so that error handling is assured of working. }
- LargeIconHandle := nil;
-
- { Determine the depth of the screen. }
- ScreenDepth := GetScreenDepth;
-
- { Now attempt to find the highest depth LargeIcon available. }
- LargeIconDepth := ScreenDepth;
- LargeIconHandle := GetLargeIcon(LargeIconID, LargeIconDepth);
- { Check to make sure that a LargeIcon was indeed able to be found. }
- if LargeIconHandle = nil then
- HandleFailure(resNotFound);
-
- { Now we must differentiate between the plotting of a Black&White }
- { LargeIcon and a color LargeIcon. }
- if LargeIconDepth > 1 then
-
- { Handle the plotting of a color LargeIcon. }
- { We must send the handle to the LargeIcon, the resID of the LargeIcon's }
- { mask (which is the ICN# ID), the depth of the LargeIcon (which is }
- { either 4 or 8), and the desired location of the upper left corner. }
- begin
- PlotCLargeIcon(LargeIconHandle, LargeIconID, LargeIconDepth, Location);
- end
-
- else
-
- { Handle the plotting of a black&White LargeIcon. }
- { We must send the handle to the LargeIcon, and the desired location of }
- { the upper left corner. }
- begin
- PlotBWLargeIcon(LargeIconHandle, Location);
- end;
-
- { Release the icon resource handle. }
- ReleaseResource(LargeIconHandle);
-
- end;
- {------------------------------------------- }
- { End of procedure PlotLargeIcon }
- {------------------------------------------- }
-
-
- {----------------------------------------------------------- }
- { End of the utility unit ResForkUtilities }
- {----------------------------------------------------------- }
- end.